import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;

import java.net.*;

/**
 * The main <code>JFrame</code> for the application.
 */
public class View extends JFrame implements ActionListener, MouseWheelListener {
	
	private boolean gameInProgress = false;	// whether or not there is a current game
	
	private TablePanel panel;
	private PlayerModel pm;
	private Model parent;
	
	private JMenuBar menuBar;
	private JMenu fileMenu, cardMenu, snapSubMenu, tableMenu, colourSubMenu, serverMenu;
	private JMenuItem fQuitMenuItem;
	private JMenuItem cFlipMenuItem;
	private JMenuItem cShuffleMenuItem;
	private JMenuItem sConnectMenuItem;
	private JRadioButtonMenuItem tcGreenTableRadio, tcRedTableRadio, tcBlueTableRadio;
	private JRadioButtonMenuItem csEnableCardSnapRadio, csDisableCardSnapRadio;
	
	AffineTransform at;
	
	/**
	 * <ul><li>Constructs the <code>JFrame</code>.</li>
	 * <li>Connects to the {@link Model}.</li>
	 * <li>Creates the menu.</li></ul>
	 * 
	 * @param parent The <code>Model</code> to connect to.
	 */
	public View(Model parent) {
		
		super("Super Awesome Cards Win");
		
		menuBar = new JMenuBar();
		fileMenu = new JMenu("File");
		fileMenu.setMnemonic(KeyEvent.VK_F);
		menuBar.add(fileMenu);
			fQuitMenuItem = new JMenuItem("Quit", KeyEvent.VK_Q);
				KeyStroke ctrlQKeyStroke = KeyStroke.getKeyStroke("control Q");
				fQuitMenuItem.setAccelerator(ctrlQKeyStroke);
				fileMenu.add(fQuitMenuItem);
				fQuitMenuItem.addActionListener(this);
				
		cardMenu = new JMenu("Card");
		cardMenu.setMnemonic(KeyEvent.VK_C);
		menuBar.add(cardMenu);
			cFlipMenuItem = new JMenuItem("Flip", KeyEvent.VK_F);
				KeyStroke fKeyStroke = KeyStroke.getKeyStroke("F");
				cFlipMenuItem.setAccelerator(fKeyStroke);
				cardMenu.add(cFlipMenuItem);
				cFlipMenuItem.addActionListener(this);
			cShuffleMenuItem = new JMenuItem("Shuffle", KeyEvent.VK_S);
				KeyStroke sKeyStroke = KeyStroke.getKeyStroke("S");
				cShuffleMenuItem.setAccelerator(sKeyStroke);
				cardMenu.add(cShuffleMenuItem);
				cShuffleMenuItem.addActionListener(this);
			snapSubMenu = new JMenu("Card Snap");
			cardMenu.add(snapSubMenu);
				ButtonGroup snap = new ButtonGroup();
				csEnableCardSnapRadio = new JRadioButtonMenuItem("Enable");
				csDisableCardSnapRadio = new JRadioButtonMenuItem("Disable");
				snapSubMenu.add(csEnableCardSnapRadio);
				snapSubMenu.add(csDisableCardSnapRadio);
				snap.add(csEnableCardSnapRadio);
				snap.add(csDisableCardSnapRadio);
				csEnableCardSnapRadio.setSelected(true);
				csEnableCardSnapRadio.addActionListener(this);
				csDisableCardSnapRadio.addActionListener(this);
				
			
		tableMenu = new JMenu("Table");
		tableMenu.setMnemonic(KeyEvent.VK_T);
		menuBar.add(tableMenu);
			colourSubMenu = new JMenu("Table Colour");
			tableMenu.add(colourSubMenu);
				ButtonGroup colour = new ButtonGroup();
				tcGreenTableRadio = new JRadioButtonMenuItem("Green");
				tcRedTableRadio = new JRadioButtonMenuItem("Red");
				tcBlueTableRadio = new JRadioButtonMenuItem("Blue");
				colourSubMenu.add(tcGreenTableRadio);
				colourSubMenu.add(tcRedTableRadio);
				colourSubMenu.add(tcBlueTableRadio);
				colour.add(tcGreenTableRadio);
				colour.add(tcRedTableRadio);
				colour.add(tcBlueTableRadio);
				tcGreenTableRadio.setSelected(true);
				tcGreenTableRadio.addActionListener(this);
				tcRedTableRadio.addActionListener(this);
				tcBlueTableRadio.addActionListener(this);
				
		serverMenu = new JMenu("Server");
		tableMenu.setMnemonic(KeyEvent.VK_S);
		menuBar.add(serverMenu);
			sConnectMenuItem = new JMenuItem("Connect", KeyEvent.VK_C);
				serverMenu.add(sConnectMenuItem);
				sConnectMenuItem.addActionListener(this);
		
		
		
		this.setJMenuBar(menuBar);
		
		setModel(parent);
		setPlayer(null);
		
		this.addWindowListener(new WL());
		this.setPreferredSize(new Dimension(800,600));
		this.pack();
		this.setVisible(true);		
		repaint();
	}
	
	/**
	 * Sets the {@link Model} that this frame is connected to.
	 * 
	 * @param m The model to set.
	 */
	public void setModel(Model m) {
		parent = m;
	}
	
	public void setPlayer(PlayerModel pm){
		this.pm = pm;
		if (pm==null) {
			Dbg.logln("View.setPlayer(null)");
			gameInProgress = false;
			JPanel currentpanel = new JPanel();
			this.setContentPane(currentpanel);
			this.pack();
			repaint();
		} else {
			Dbg.logln("View.setPlayer(PLAYER)");
			gameInProgress = true;
			panel = new TablePanel(pm);
			panel.addMouseWheelListener(this);
			this.setContentPane(panel);
			this.pack();
			repaint();
			panel.forceRepaint();
		}
	}
	
	/**
	 * The <code>WindowAdapter</code> that listens for <code>windowClosing</code> events.
	 */
	public class WL extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}
	
	/**
	 * Processes mouse events for the menus.
	 */
	public void actionPerformed(ActionEvent ae){
		
		if (gameInProgress) {
			Object source = ae.getSource();
			
			if(source == fQuitMenuItem){
				//close
				System.exit(0);
				
			} else if(source == cFlipMenuItem){
				pm.flipSelected();
			} else if(source == cShuffleMenuItem){
				pm.shuffleSelected();
				panel.repaint();
			} else if(source == tcGreenTableRadio) {
				System.out.println("Change table colour to - green");
				panel.changeBackgroundColour("green");
			} else if(source == tcRedTableRadio) {
				System.out.println("Change table colour to - red");
				panel.changeBackgroundColour("red");
			} else if(source == tcBlueTableRadio) {
				System.out.println("Change table colour to - blue");
				panel.changeBackgroundColour("blue");
			} else if(source == sConnectMenuItem) {
				System.out.println("Server Connect");
				doConnectionDialog();
			} else if(source == csEnableCardSnapRadio) {
				System.out.println("Snap Enabled");
				parent.setSnap(true);
			} else if(source == csDisableCardSnapRadio) {
				System.out.println("Snap Disabled");
				parent.setSnap(false);
			}
		}
		
	}
	
	public void alert(String msg) {
		JOptionPane.showMessageDialog(null, msg);
	}

	public void mouseWheelMoved(MouseWheelEvent mw) {
		if (gameInProgress) {
			panel.zoom(mw.getWheelRotation());
			repaint();
		}
	}
	
	public void doConnectionDialog() {
		
		//remove hardcoded ip address
		String server = JOptionPane.showInputDialog(null, "Enter Server host", "192.168.1.108");
		
		if(server == null)
			return;
			
		String p = JOptionPane.showInputDialog(null, "Enter Server port", "1099");
		
		if(p == null)
			return;
			
		try {
			int port = Integer.valueOf(p);
			
			if(parent.connectToRemoteServer(server, port)){
				alert("Connected");
			} else {
				alert("Failed");
			}
		}
		catch(NumberFormatException nfe){
			alert("Invalid Input - ABORTING");
		}
	}
	
	public void repaint() {
		Dbg.logln("View.repaint");
		super.repaint();
	}
}
